package com.beiding.service.user;

import com.beiding.dao.UserDao;
import com.beiding.exception.NotFoundException;
import com.beiding.exception.RegisterException;
import com.beiding.pojo.auth.User;
import com.beiding.service.Authorities;
import com.google.common.collect.Sets;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Principal;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    private PasswordEncoder passwordEncoder;

    //在注销用户的时候进行广播.由于无法级联,所以只能手动删除
    private RabbitTemplate rabbitTemplate;


    public UserServiceImpl(UserDao userDao, PasswordEncoder passwordEncoder, RabbitTemplate rabbitTemplate) {
        this.userDao = userDao;
        this.passwordEncoder = passwordEncoder;
        this.rabbitTemplate = rabbitTemplate;


        //尝试从数据库中获取admin用户,如果没有admin用户就创建

        Optional<User> optional = userDao.findById("admin");

        if (!optional.isPresent()) {
            User user = new User();
            user.setUsername("admin");

            //初始初始密码为admin
            user.setPassword("admin");

            //没有邮箱,需要管理员后期手动修改添加
            user.setEmail("-@-");

            user.afterSetProperties(passwordEncoder);

            //具有全部权限
            user.setAuthorities(Sets.newHashSet(Authorities.ALL));

            //保存admin用户
            userDao.save(user);
        }

    }

    @Override
    public void changePassword(String name, String newPassword) {
        userDao.updateField(name, "password", passwordEncoder.encode(newPassword));
    }

    @Override
    @Secured("ROLE_USER")
    public void changeEmail(String name, String newEmail) {
        userDao.updateField(name, "email", newEmail);
    }

    @Transactional
    @Override
    public void save(User user) {

        if (userDao.existsById(user.getUsername())) {
            throw new RegisterException("username", "用户名已存在");
        }


        //初始化用户,为了防止前端提交的不认可的数据
        user.afterSetProperties(passwordEncoder);

        userDao.save(user);
    }

    @Override
    public boolean checkPassword(String name, String oldPassword) {

        final Optional<User> optional = userDao.findByIdLimitFields(name, "password");

        return optional.filter(userLocal -> passwordEncoder.matches(oldPassword, userLocal.getPassword())).isPresent();

    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<User> optional = userDao.findById(username);
        if (optional.isPresent()) {
            return optional.get().user();
        }

        throw new UsernameNotFoundException("不存在用户");
    }


    @Override
    public void addAuthority(String name, GrantedAuthority authority) {
        //添加权限
        if (!userDao.containerContains(name, "authorities", authority)) {
            userDao.containerAppend(name, "authorities", authority);
        }
    }

    @Override
    public String getEmail(String name) {

        Optional<User> optional = userDao.findByIdLimitFields(name, "email");

        if (optional.isPresent()) {
            return optional.get().getEmail();
        }

        throw new NotFoundException("没有这个用户");
    }

    @Override
    @Secured("ROLE_USER")
    public void unsubscribe(Principal principal) {
        userDao.deleteById(principal.getName());

        //删除用户的时候发起一个广播,删除当前用户的所有资源

        //rabbitTemplate.convertAndSend(UserAmqpConfig., principal.getName());
    }

    @Override
    public User getUser(String username) {


        Optional<User> optional = userDao.findByIdLimitFields(username, "incompleteEmail", "email");

        if (optional.isPresent()) {
            return optional.get();
        }

        throw new NotFoundException("没有这个用户");
    }


}
